package com.cangxuan.backend.controller;

import com.alibaba.fastjson.JSONObject;
import com.cangxuan.backend.annotation.Check;
import com.cangxuan.backend.annotation.check.NotEmpty;
import com.cangxuan.backend.entity.MarketGoods;
import com.cangxuan.backend.entity.User;
import com.cangxuan.backend.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.Data;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.io.*;
import java.util.*;

/**
 * 用户相关接口
 */
@Api(tags = "用户相关接口")
@RestController
@RequestMapping("user")
public class UserController extends BaseController {


    IUserService userService;

    @Autowired
    public void setUserService(IUserService userService) {
        this.userService = userService;
    }

    @Data
    public static class UserChangeNicknameBody {
        @NotEmpty(message = "请传递nickname")
        private String nickname;    //新的昵称
    }

    @Data
    public static class UserChangeTransPassword {
        @NotEmpty(message = "transPassword")
        private String transPassword;    //新的交易密码
        private String oldTransPassword;    //新的交易密码
    }

    @Data
    public static class UserGetFaceBase64 {
        @NotEmpty(message = "请传递faced的Base64编码")
        private String facePath;    //新的头像Base64码
    }

    @GetMapping("privacy")
    @ApiOperation("【需要登陆】获取隐私设置")
    public Object privacy() {
        List<Boolean> list = new ArrayList<>();
        User currentUser = userService.getCurrentUser();
        list.add(currentUser.isDisplayMyGoods());
        list.add(currentUser.isDisplayMySellGoods());
        return success(list);
    }

    @GetMapping("setPrivacyUpdateDisplayMyGoods/{isChecked}")
    @ApiOperation("【需要登录】设置隐私设置：是否对外展示拥有的藏品")
    public Object setPrivacyUpdateDisplayMyGoods(@ApiParam("0：false，1：true") @PathVariable byte isChecked) {
        return userService.updateDisplayMyGoods(isChecked) ? success() : fail(500, "修改失败");
    }

    @GetMapping("setPrivacyUpdateDisplayMySellGoods/{isChecked}")
    @ApiOperation("【需要登录】设置隐私设置:是否对外展示出售的藏品")
    public Object setPrivacyUpdateDisplayMySellGoods(@ApiParam("0：false，1：true") @PathVariable byte isChecked) {
        return userService.updateDisplayMySellGoods(isChecked) ? success() : fail(500, "修改失败");
    }

    @PostMapping("changeTransPassword")
    @ApiOperation("【需要登录】修改交易密码")
    public Object changeTransPassword(@Check @RequestBody UserChangeTransPassword userChangeTransPassword) {
        Integer integer = userService.changeTransPassword(userChangeTransPassword.getTransPassword(), userChangeTransPassword.getOldTransPassword());
        return success(integer);
    }

    @GetMapping("getBlockchain/{userId}")
    public Object getBlockchain(@PathVariable Long userId){
        return userService.getBlockChain(userId);
    }

    @Data
    public static class UserChangeSubscribeToTheSalesCalendar {
        @NotEmpty(message = "请传递true/false")
        private Boolean subscribe;    //新的订阅设置

        public UserChangeSubscribeToTheSalesCalendar(Boolean subscribe) {
            this.subscribe = subscribe;
        }

        public UserChangeSubscribeToTheSalesCalendar() {

        }

    }

    @PostMapping("changeSubscribeToTheSalesCalendar")
    @ApiOperation("【需要登录】修改订阅")
    public Object changeSubscribeToTheSalesCalendar(@Check @RequestBody UserChangeSubscribeToTheSalesCalendar userChangeSubscribeToTheSalesCalendar) {
        userService.changeTheSalesCalendar(userChangeSubscribeToTheSalesCalendar.getSubscribe());
        return success("修改成功");
    }

    /**
     * 修改昵称
     * 不限会员权限
     *
     * @param userChangeNicknameBody
     * @return
     */
    @PostMapping("changeNickname")
    @ApiOperation("【需要登录】修改用户昵称")
    public Object changeNickname(@Check @RequestBody UserChangeNicknameBody userChangeNicknameBody) {
        userService.changeNickname(userChangeNicknameBody.getNickname());
        return success("修改成功");
    }

    /**
     * 查看用户是否关注接口
     *
     * @param goodsId
     * @return
     */
    @GetMapping("viewFollow/{goodsId}")
    @ApiOperation("【需要登录】查看用户是否关注接口")
    public Object viewFollow(@ApiParam("藏品Id") @PathVariable("goodsId") int goodsId) {
        userService.viewFollow(goodsId);
        return success("已关注");
    }

    /**
     * 添加用户关注接口
     *
     * @param goodsId
     * @return
     */
    @GetMapping("addFollow/{goodsId}")
    @ApiOperation("【需要登录】添加用户关注")
    public Object addFollow(@ApiParam("藏品Id") @PathVariable("goodsId") int goodsId) {
        userService.addFollow(goodsId);
        return success("已关注");
    }

    /**
     * 取消用户关注接口
     *
     * @param goodsId
     * @return
     */
    @GetMapping("cancelFollow/{goodsId}")
    @ApiOperation("【需要登录】取消用户关注")
    public Object cancelFollow(@ApiParam("藏品Id") @PathVariable("goodsId") int goodsId) {
        userService.cancelFollow(goodsId);
        return success("已取消");
    }


    /**
     * 获取市场关注列表
     *
     * @return
     */
    @GetMapping("followGoods/{pageIndex}")
    @ApiOperation("【需要登录】获取用户关注商品")
    public Object getFollowGoods(@PathVariable int pageIndex) {
        List<MarketGoods> goods = userService.getFollowGoods(pageIndex);
        return success(goods);
    }

    @Data
    public static class Card {
        private String realName;    //真实姓名
        private String idCard;    //身份证号
        private String other;    //图片Base64编码
    }

    @PostMapping("proveAndUpdateIdentifyInformation")
    @ApiOperation("【需要登录】认证用户信息并更新")
    public Object getIdentifyInformation(@Check @RequestBody Card card) throws IOException {

        if ((card.getRealName().length() >= 10)) {
            return fail(402, "姓名长度请不要超过10位");
        }

        if (!isValidIDCardFormat(card.getIdCard())) {
            return fail(402, "身份证格式错误");
        }

        String imageBase64 = card.getOther();

        Map<String, String> params = new HashMap<>();
        params.put("idcard", card.getIdCard());
        params.put("name", card.getRealName());
        params.put("image", imageBase64);
        String jsonResult = postForm("dcdac9deb1574d82b1dca627de1fa033", "https://faceidcardb.shumaidata.com/getfaceidb", params);
        System.out.println("jsonResult:" + jsonResult);
        JSONObject jsonResponse = JSONObject.parseObject(jsonResult);
        JSONObject jsonData = jsonResponse.getJSONObject("data");
        if(jsonData==null){
            return fail(401,"认证失败");
        }
        if (jsonData.getInteger("incorrect") == 100) {
            //更新用户的身份信息到数据库
            userService.updateUserInformation(card.getRealName(), card.getIdCard(), getCurrentUser().getId());
            //保存图片
            // Decode Base64 string to byte array
            byte[] data = Base64.getDecoder().decode(imageBase64);
            // Create a file object
            FileOutputStream fileOutputStream = null;

            File file = new File(webPath + "/upload/photo/" + getCurrentUser().getId() + ".jpg");
            try {
                fileOutputStream = new FileOutputStream(file);
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            }
            //下面是使用缓冲输出流
            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
            //循环字节数组，将每个字节写入到缓冲输出流
            for (byte b1 : data) {
                try {
                    bufferedOutputStream.write(b1);

                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            //关闭缓冲输出流
            bufferedOutputStream.close();
            //关闭输出流
            fileOutputStream.close();
            return success();
        } else {
            return fail(402, "实名认证失败，请检查您的姓名、身份证号码、图片是否是您本人的");
        }
    }

    /**
     * 用到的HTTP工具包：okhttp 3.13.1
     * <dependency>
     * <groupId>com.squareup.okhttp3</groupId>
     * <artifactId>okhttp</artifactId>
     * <version>3.13.1</version>
     * </dependency>
     */
    public static String postForm(String appCode, String url, Map<String, String> params) throws IOException {
        OkHttpClient client = new OkHttpClient.Builder().build();
        FormBody.Builder formbuilder = new FormBody.Builder();
        Iterator<String> it = params.keySet().iterator();
        while (it.hasNext()) {
            String key = it.next();
            formbuilder.add(key, params.get(key));
            System.out.println("key:" + key);
        }
        FormBody body = formbuilder.build();
        Request request = new Request.Builder().url(url).addHeader("Authorization", "APPCODE " + appCode).post(body).build();
        Response response = client.newCall(request).execute();
        System.out.println("返回状态码" + response.code() + ",message:" + response.message());
        String result = response.body().string();
        return result;
    }

    //身份验证方法
    public static boolean isValidIDCardFormat(String idCard) {
        if (idCard == null) {
            return false;
        }
        String pattern = "(^\\d{15}$)|(^\\d{17}([0-9]|X)$)";
        return idCard.matches(pattern);
    }

    @Value("${webPath}")
    String webPath;

    @PostMapping("getFaceBase64")
    @ApiOperation("获取头像的Base64码")
    public Object getFaceBase64(@Check @RequestBody UserGetFaceBase64 userGetFaceBase64Body) throws IOException {
        String path = webPath + "/upload/face/" + System.currentTimeMillis() + ".jpg";
        byte[] data = Base64.getDecoder().decode(userGetFaceBase64Body.facePath);
        FileOutputStream fileOutputStream = null;
        File file = new File(path);
        try {
            fileOutputStream = new FileOutputStream(file);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
        //下面是使用缓冲输出流
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
        //循环字节数组，将每个字节写入到缓冲输出流
        for (byte b1 : data) {
            try {
                bufferedOutputStream.write(b1);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        //关闭缓冲输出流
        bufferedOutputStream.close();
        //关闭输出流
        fileOutputStream.close();
        userService.changeFacePath(path);
        return success("修改成功");

    }

}